import type { Field } from '@directus/types';
import { describe, expect, it } from 'vitest';
import { getRevisionFields } from './get-revision-fields';

describe('getRevisionFields', () => {
	it('should filter out random fields', () => {
		const fields = getFieldData();
		const allFields = fields.map((field) => field.field);
		const randomFields = ['non_existing_field_1', 'non_existing_field_2'];
		const revisionFields = getRevisionFields([...allFields, ...randomFields], fields);

		expect(revisionFields).not.toEqual(expect.arrayContaining(randomFields));
		expect(revisionFields).toEqual(['title', 'description', 'hide_description']);
	});

	it('should not contain relational fields', () => {
		const fields = getFieldData();
		const allFields = fields.map((field) => field.field);
		const revisionFields = getRevisionFields(allFields, fields);

		expect(revisionFields).not.toEqual(expect.arrayContaining(['m2o', 'o2m', 'm2m', 'm2a']));
		expect(revisionFields).toEqual(['title', 'description', 'hide_description']);
	});

	it('should not contain user-created/-updated or date-created/-updated fields if they are hidden', () => {
		const fields = getFieldData();
		const allFields = fields.map((field) => field.field);
		const revisionFields = getRevisionFields(allFields, fields);

		expect(revisionFields).not.toEqual(
			expect.arrayContaining(['created_by', 'created_at', 'updated_by', 'updated_at']),
		);

		expect(revisionFields).toEqual(['title', 'description', 'hide_description']);
	});

	it('should contain user-created/-updated or date-created/-updated fields if they are visible', () => {
		const fields = getFieldData({ hideUserFields: false, hideDateFields: false });
		const allFields = fields.map((field) => field.field);
		const revisionFields = getRevisionFields(allFields, fields);

		expect(revisionFields).toEqual(expect.arrayContaining(['created_by', 'created_at', 'updated_by', 'updated_at']));
	});
});

function getFieldData({ hideUserFields = true, hideDateFields = true } = {}): Field[] {
	const collection = 'test_collection';

	return [
		{
			collection: collection,
			field: 'created_by',
			type: 'string',
			schema: {
				name: 'created_by',
				table: collection,
				data_type: 'char',
				default_value: null,
				max_length: 36,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: true,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: 'id',
				foreign_key_table: 'directus_users',
			},
			meta: {
				id: 193,
				collection: collection,
				field: 'created_by',
				special: ['user-created'],
				interface: 'select-dropdown-m2o',
				options: {
					template: '{{avatar}} {{first_name}} {{last_name}}',
				},
				display: 'user',
				display_options: null,
				readonly: true,
				hidden: hideUserFields,
				sort: 2,
				width: 'half',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'Created By',
		},
		{
			collection: collection,
			field: 'created_at',
			type: 'timestamp',
			schema: {
				name: 'created_at',
				table: collection,
				data_type: 'datetime',
				default_value: null,
				max_length: null,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: true,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: null,
				foreign_key_table: null,
			},
			meta: {
				id: 194,
				collection: collection,
				field: 'created_at',
				special: ['date-created', 'cast-timestamp'],
				interface: 'datetime',
				options: null,
				display: 'datetime',
				display_options: {
					relative: true,
				},
				readonly: true,
				hidden: hideDateFields,
				sort: 3,
				width: 'half',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'Created At',
		},
		{
			collection: collection,
			field: 'updated_by',
			type: 'string',
			schema: {
				name: 'updated_by',
				table: collection,
				data_type: 'char',
				default_value: null,
				max_length: 36,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: true,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: 'id',
				foreign_key_table: 'directus_users',
			},
			meta: {
				id: 195,
				collection: collection,
				field: 'updated_by',
				special: ['user-updated'],
				interface: 'select-dropdown-m2o',
				options: {
					template: '{{avatar}} {{first_name}} {{last_name}}',
				},
				display: 'user',
				display_options: null,
				readonly: true,
				hidden: hideUserFields,
				sort: 4,
				width: 'half',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'Updated By',
		},
		{
			collection: collection,
			field: 'updated_at',
			type: 'timestamp',
			schema: {
				name: 'updated_at',
				table: collection,
				data_type: 'datetime',
				default_value: null,
				max_length: null,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: true,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: null,
				foreign_key_table: null,
			},
			meta: {
				id: 196,
				collection: collection,
				field: 'updated_at',
				special: ['date-updated', 'cast-timestamp'],
				interface: 'datetime',
				options: null,
				display: 'datetime',
				display_options: {
					relative: true,
				},
				readonly: true,
				hidden: hideDateFields,
				sort: 5,
				width: 'half',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'Updated At',
		},
		{
			collection: collection,
			field: 'title',
			type: 'string',
			schema: {
				name: 'title',
				table: collection,
				data_type: 'varchar',
				default_value: null,
				max_length: 255,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: true,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: null,
				foreign_key_table: null,
			},
			meta: {
				id: 197,
				collection: collection,
				field: 'title',
				special: null,
				interface: 'input',
				options: null,
				display: null,
				display_options: null,
				readonly: false,
				hidden: false,
				sort: 6,
				width: 'full',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'Title',
		},
		{
			collection: collection,
			field: 'description',
			type: 'text',
			schema: {
				name: 'description',
				table: collection,
				data_type: 'text',
				default_value: null,
				max_length: null,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: true,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: null,
				foreign_key_table: null,
			},
			meta: {
				id: 198,
				collection: collection,
				field: 'description',
				special: null,
				interface: 'input-multiline',
				options: null,
				display: null,
				display_options: null,
				readonly: false,
				hidden: false,
				sort: 7,
				width: 'half',
				translations: null,
				note: null,
				conditions: [
					{
						name: 'Hide if toggle is enabled',
						rule: {
							_and: [
								{
									hide_description: {
										_eq: true,
									},
								},
							],
						},
						hidden: false,
					},
				],
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'Description',
		},
		{
			collection: collection,
			field: 'hide_description',
			type: 'boolean',
			schema: {
				name: 'hide_description',
				table: collection,
				data_type: 'boolean',
				default_value: false,
				max_length: null,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: false,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: null,
				foreign_key_table: null,
			},
			meta: {
				id: 199,
				collection: collection,
				field: 'hide_description',
				special: ['cast-boolean'],
				interface: 'boolean',
				options: null,
				display: null,
				display_options: null,
				readonly: false,
				hidden: false,
				sort: 8,
				width: 'half',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'Hide Description',
		},
		{
			collection: collection,
			field: 'm2o',
			type: 'integer',
			schema: {
				name: 'm2o',
				table: collection,
				data_type: 'integer',
				default_value: null,
				max_length: null,
				numeric_precision: null,
				numeric_scale: null,
				is_generated: false,
				generation_expression: null,
				is_nullable: true,
				is_unique: false,
				is_indexed: false,
				is_primary_key: false,
				has_auto_increment: false,
				foreign_key_column: 'id',
				foreign_key_table: collection,
			},
			meta: {
				id: 200,
				collection: collection,
				field: 'm2o',
				special: ['m2o'],
				interface: 'select-dropdown-m2o',
				options: {
					template: '{{title}}',
				},
				display: null,
				display_options: null,
				readonly: false,
				hidden: false,
				sort: 9,
				width: 'full',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'M2O',
		},
		{
			collection: collection,
			field: 'o2m',
			type: 'alias',
			schema: null,
			meta: {
				id: 201,
				collection: collection,
				field: 'o2m',
				special: ['o2m'],
				interface: 'list-o2m',
				options: {
					sort: null,
					template: '{{title}}',
				},
				display: null,
				display_options: null,
				readonly: false,
				hidden: false,
				sort: 10,
				width: 'full',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'O2M',
		},
		{
			collection: collection,
			field: 'm2m',
			type: 'alias',
			schema: null,
			meta: {
				id: 203,
				collection: collection,
				field: 'm2m',
				special: ['m2m'],
				interface: 'list-m2m',
				options: {
					layout: 'table',
					fields: [`${collection}_id.title`],
				},
				display: null,
				display_options: null,
				readonly: false,
				hidden: false,
				sort: 12,
				width: 'full',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'M2M',
		},
		{
			collection: collection,
			field: 'm2a',
			type: 'alias',
			schema: null,
			meta: {
				id: 207,
				collection: collection,
				field: 'm2a',
				special: ['m2a'],
				interface: 'list-m2a',
				options: null,
				display: null,
				display_options: null,
				readonly: false,
				hidden: false,
				sort: 13,
				width: 'full',
				translations: null,
				note: null,
				conditions: null,
				required: false,
				group: null,
				validation: null,
				validation_message: null,
			},
			name: 'M2A',
		},
	];
}
